<?php
namespace Com\AibeiPay;
use Duobao\Controller\LogController as Mylog;

class AibeiPay{
    protected $appkey = '';
    protected $platpkey = '';
    protected $orderurl ='http://ipay.iapppay.com:9999/payapi/order';

    public function __construct()
    {
        $this->appkey = C('aibei_appkey');
        $this->platpkey = C('aibei_platpkey');
    }

    /**
     * 获取爱贝的流水号，再通过流水号发起支付
     */
    public function trade($goods_id,$order,$price,$user_id){
        //下单接口
        $orderReq = array();
        $orderReq['appid'] = C('aibei_appid');//爱贝支付中的商户id
        $orderReq['waresid'] = $goods_id;//应用中商品的编号
        $orderReq['cporderid'] = $order;//订单编号，需唯一
        $orderReq['price'] = $price;//商品的价格
        $orderReq['currency'] = 'RMB';
        $orderReq['appuserid'] ="$user_id";
        $orderReq['cpprivateinfo'] = hash('sha256','lightrain');//商户私有信息，支付完成后发送支付结果通知时会透传给商户
        $orderReq['notifyurl'] = C("APP_URL").'/Notify/aibei_pay_notify';
        $reqData = $this->composeReq($orderReq,$this->appkey);//组装请求报文

        //发送到爱贝服务后台请求下单
        $respData = $this->request_by_curl($this->orderurl, $reqData, 'order test');

//        Mylog::write($respData);

        //验签数据并且解析返回报文
        if(!$this->parseResp($respData, $this->platpkey, $respJson)) {
            Mylog::write('爱贝支付服务器下单失败。respData:'.$respData);
            return false;
        }else{
            //下单成功返回请求报文

           return $respJson->transid;
        }
    }

    private function composeReq($reqJson, $vkey) {
        //获取待签名字符串
        $content = json_encode($reqJson);
        //格式化key，建议将格式化后的key保存，直接调用
        $vkey = $this->formatPriKey($vkey);

        //生成签名
        $sign = $this->sign($content, $vkey);

        //组装请求报文，目前签名方式只支持RSA这一种
        $reqData = "transdata=".urlencode($content)."&sign=".urlencode($sign)."&signtype=RSA";

        return $reqData;
    }

     /**格式化公钥
     * $priKey PKCS#1格式的私钥串
     * return pem格式私钥， 可以保存为.pem文件
     */
    private function formatPriKey($priKey) {
        $fKey = "-----BEGIN RSA PRIVATE KEY-----\n";
        $len = strlen($priKey);
        for($i = 0; $i < $len; ) {
            $fKey = $fKey . substr($priKey, $i, 64) . "\n";
            $i += 64;
        }
        $fKey .= "-----END RSA PRIVATE KEY-----";
        return $fKey;
    }

    /**格式化公钥
     * $pubKey PKCS#1格式的公钥串
     * return pem格式公钥， 可以保存为.pem文件
     */
    private function formatPubKey($pubKey) {
        $fKey = "-----BEGIN PUBLIC KEY-----\n";
        $len = strlen($pubKey);
        for($i = 0; $i < $len; ) {
            $fKey = $fKey . substr($pubKey, $i, 64) . "\n";
            $i += 64;
        }
        $fKey .= "-----END PUBLIC KEY-----";
        return $fKey;
    }

    /**RSA签名
     * $data待签名数据
     * $priKey商户私钥
     * 签名用商户私钥
     * 使用MD5摘要算法
     * 最后的签名，需要用base64编码
     * return Sign签名
     */
   public function sign($data, $priKey) {
        //转换为openssl密钥
        $res = openssl_get_privatekey($priKey);

        //调用openssl内置签名方法，生成签名$sign
        openssl_sign($data, $sign, $res, OPENSSL_ALGO_MD5);

        //释放资源
        openssl_free_key($res);

        //base64编码
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * curl方式发送post报文
     * $remoteServer 请求地址
     * $postData post报文内容
     * $userAgent用户属性
     * return 返回报文
     */
    private function request_by_curl($remoteServer, $postData, $userAgent) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $remoteServer);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
        $data = urldecode(curl_exec($ch));
        curl_close($ch);

        return $data;
    }

    /**
     * 解析response报文
     * $content  收到的response报文
     * $pkey     爱贝平台公钥，用于验签
     * $respJson 返回解析后的json报文
     * return    解析成功TRUE，失败FALSE
     */
    public function parseResp($content, $pkey, &$respJson) {
        $arr=array_map(create_function('$v', 'return explode("=", $v);'), explode('&', $content));
        foreach($arr as $value) {
            $resp[($value[0])] = $value[1];
        }

        //解析transdata
        if(array_key_exists("transdata", $resp)) {
            $respJson = json_decode($resp["transdata"]);
        } else {
            return FALSE;
        }

        //验证签名，失败应答报文没有sign，跳过验签
        if(array_key_exists("sign", $resp)) {
            //校验签名
            $pkey = $this->formatPubKey($pkey);
            return $this->verify($resp["transdata"], $resp["sign"], $pkey);
        } else if(array_key_exists("errmsg", $respJson)) {
            return FALSE;
        }

        return TRUE;
    }

    /**RSA验签
     * $data待签名数据
     * $sign需要验签的签名
     * $pubKey爱贝公钥
     * 验签用爱贝公钥，摘要算法为MD5
     * return 验签是否通过 bool值
     */
    private function verify($data, $sign, $pubKey)  {
        //转换为openssl格式密钥
        $res = openssl_get_publickey($pubKey);

        //调用openssl内置方法验签，返回bool值
        $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_MD5);

        //释放资源
        openssl_free_key($res);

        //返回资源是否成功
        return $result;
    }

    public function H5orPCpay($transid,$notify_url) {
        //下单接口
        $orderReq['transid'] = "$transid";
        $orderReq['redirecturl'] = $notify_url;
        //组装请求报文   对数据签名
        $reqData = $this->composeReq($orderReq, C('aibei_appkey'));

        echo "<script language=\"javascript\">";
        echo "location.href=\"https://web.iapppay.com/h5/exbegpay?$reqData\"";//我们的常连接版本 有PC 版本 和移动版本。 根据使用的环境不同请更换相应的URL:$h5url,$pcurl.
        echo "</script>";
    }

    /* end of aibeipay */
}